#define MaxLights 2


float4x4	World;
float4x4	View;
float4x4	Projection;

int activePointLights;
float3      LightPointPosition[MaxLights];
float4		LightPointColor[MaxLights];

int activeSpotLights;
float3		lightSpotDirection[MaxLights];
float		lightSpotDecayExponent[MaxLights];
float		lightSpotAngleCosine[MaxLights];

float3      LightSpotPosition[MaxLights];
float4		LightSpotColor[MaxLights];

float4		SpecularColor;
float		SpecularPower;
float		SpecularIntensity;
float4      AmbientColor;
float		AmbientIntensity;
float		DiffuseIntensity;


float3      camPosition;

struct VertexShaderInput
{
    float3 Position : POSITION0;
	float3 Normal : Normal0;
	float2 TexCoord : TexCoord0;
};


struct VertexShaderOutput
{
    float4 Position			: POSITION0;	        
    float3 N				: TEXCOORD0;     
	float2 TextureCoord		: TEXCOORD1;     
	float3 V				: TEXCOORD2;
	float3 WorldPosition	: TEXCOORD3;
	
};


VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;
	
    float4 worldPosition = mul(float4(input.Position,1), World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);
	
	output.N = mul(float4(input.Normal,0), World);
	output.TextureCoord = input.TexCoord;
    output.V = camPosition -  worldPosition;	
	output.WorldPosition = worldPosition;
    return output;
}


float4 PixelShaderAmbientFunction(VertexShaderOutput input) : COLOR0
{
	float4 finalColor = float4(0,0,0,0);
	float4 diffuseColor = float4(1,1,1,1);
	float3 Normal = normalize(input.N);
	float3 ViewDir = normalize(input.V);    		

	for(int i = 0 ; i < activePointLights; i ++)
	{
		float3 LightDir = normalize(LightPointPosition[i] - input.WorldPosition);
		float Diff = saturate(dot(Normal, LightDir));
		float Specular = 0;		
		if(Diff > 0)
		{     
			float3 Reflect = normalize(2 * Diff * Normal - LightDir);  
			Specular = pow(saturate(dot(Reflect, ViewDir)), SpecularPower); 
		}
		finalColor += AmbientColor*AmbientIntensity + LightPointColor[i] * DiffuseIntensity * diffuseColor * Diff + SpecularIntensity * SpecularColor * Specular; 
	}

	for(int j = 0 ; j < activeSpotLights; j ++)
	{
			float3 LightDir = LightSpotPosition[j] - input.WorldPosition;						
			LightDir = normalize(LightDir);        
			float SdL = dot(lightSpotDirection[j], -LightDir);  
 
			if(SdL > lightSpotAngleCosine[j])  
			{
				float spotIntensity = pow(SdL, lightSpotDecayExponent[j]);  
				float3 Normal = normalize(input.N);				
				float3 ViewDir = normalize(input.V);    		
				float Diff = saturate(dot(Normal, LightDir));    
				float Specular = 0; 
				if( Diff >0 )
				{
					float3 Reflect = normalize(2 * Diff * Normal - LightDir);  
					Specular = pow(saturate(dot(Reflect, ViewDir)), SpecularPower); 
				}
				finalColor += AmbientColor*AmbientIntensity + spotIntensity * LightSpotColor[j] * DiffuseIntensity * diffuseColor * Diff + SpecularIntensity * SpecularColor * Specular; 
			}
	}

	return finalColor;    
}


technique TechniqueNormal
{
	
    pass Pass1
    {        
        VertexShader = compile vs_3_0 VertexShaderFunction();
        PixelShader = compile ps_3_0 PixelShaderAmbientFunction();
    }

}

